package com.sdp.wx.handleImpl;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONObject;
import com.sdp.core.bizc.utils.ApplicationContextUtils;
import com.sdp.core.bizc.vo.BusinessContext;
import com.sdp.wx.controller.WxRepairCodeController;
import com.sdp.wx.controller.WxSysConfigController;
import com.sdp.wx.db.wx_warehouse_info.entity.WxWarehouseInfo;
import com.sdp.wx.db.wx_warehouse_info.service.IWxWarehouseInfoService;
import com.sdp.wx.db.wx_warehouse_right.service.IWxWarehouseRightService;
import com.sdp.wx.db.wx_wz_arrival.entity.WxWzArrival;
import com.sdp.wx.db.wx_wz_arrival.service.IWxWzArrivalService;
import com.sdp.wx.db.wx_wz_input.entity.WxWzInput;
import com.sdp.wx.db.wx_wz_input.service.IWxWzInputService;
import com.sdp.wx.db.wx_wz_input_detail.entity.WxWzInputDetail;
import com.sdp.wx.db.wx_wz_input_detail.service.IWxWzInputDetailService;
import com.sdp.wx.db.wx_wz_now_num.service.IWxWzNowNumService;
import com.sdp.wx.handle.WzInOutPutHandle;
import com.sdp.wx.utils.CurrentLoginEmp;
import com.sdp.wx.utils.WxConstants;

@Component
public class WzProcuredInputHandleImpl extends WzInOutPutHandle{
	
	@Autowired
	private IWxWarehouseInfoService iWxWarehouseInfoService;
	
	@Autowired
	private IWxWarehouseRightService iWxWarehouseRightService;
	
	@Autowired
	private CurrentLoginEmp currentLoginEmp;
	
	@Autowired
	private WxRepairCodeController wxRepairCodeController;
	
	@Autowired
	private IWxWzArrivalService iWxWzArrivalService;

	@Autowired
	private IWxWzInputService iWxWzInputService;
	
	@Autowired
	private IWxWzInputDetailService iWxWzInputDetailService;
	
	@Autowired
	private IWxWzNowNumService iWxWzNowNumService;
	
	@Autowired
	private WxSysConfigController wxSysConfigController;
	
	
	@Override
	public BusinessContext execute(BusinessContext businessContext) {
		return ApplicationContextUtils.getBean(WzProcuredInputHandleImpl.class).wzProcuredInput(businessContext);
	}
	
	@Transactional(rollbackFor=Exception.class)
	public BusinessContext wzProcuredInput(BusinessContext businessContext) {
		JSONObject emp = currentLoginEmp.getCurrentLoginInfo();
		if(StringUtils.isEmpty(emp)) {
			businessContext.setMessage("请先登录系统");
			businessContext.setSuccess(false);
			return businessContext;
		}
		
		List<WxWzInputDetail> wzList = businessContext.get(WxWzInputDetail.class);
		WxWzInput input = businessContext.get(WxWzInput.class);
		if(input==null || wzList==null || wzList.size()==0) {
			businessContext.setSuccess(false);
			businessContext.setMessage("入库信息为空，不能入库");
			return businessContext;
		}
		
		//查询对应的到货单是否已经入库
		WxWzArrival wxWzArrival = iWxWzArrivalService.queryWxWzArrivalByCode(input.getArrivalCode());
		if(WxConstants.是.getCode().equals(wxWzArrival.getIsInput())) {
			businessContext.setSuccess(false);
			businessContext.setMessage("选择的到货单已经入库过，不能重复入库");
			return businessContext;
		}
		//判断仓库是否锁定
		WxWarehouseInfo warehouseInfo = iWxWarehouseInfoService.queryWxWarehouseInfoByCode(input.getWarehouseCode());
		if(warehouseInfo==null || WxConstants.是.getCode().equals(warehouseInfo.getIsLock())) {
			businessContext.setMessage("仓库目前处于盘存状态，无法进行入库");
			businessContext.setSuccess(false);
			return businessContext;
		}
		//判断当前操作人是否有入库的权限
		boolean haveRight = iWxWarehouseRightService.isHaveRight(emp.getString("empNo"), input.getWarehouseCode(),WxConstants.库管权限_采购入库.getCode());
		if(!haveRight) {
			businessContext.setMessage("您没有此仓库的采购入库权限");
			businessContext.setSuccess(false);
			return businessContext;
		}
		
		LocalDateTime now = LocalDateTime.now();
		if(input.getInputTime()==null) {
			input.setInputTime(now);
		}
		
		input.setInputDate(input.getInputTime().toLocalDate());
		input.setCreateTime(now);
		input.setOpName(emp.getString("empName"));
		input.setOpNo(emp.getString("empNo"));
		input.setInputCode(wxRepairCodeController.getCode(WxConstants.流水号前缀_器材入库单.getCode(), WxConstants.流水号类型_器材入库单.getCode()));
		input.setIsUse(WxConstants.是.getCode());
		input.setIsOutput(WxConstants.否.getCode());
		
		
		Map<String,BigDecimal> wzInputNumMap = new HashMap<>();
		List<String> wzCodeList = new ArrayList<String>();
		BigDecimal inputAmount = BigDecimal.ZERO;
		String armRatio = wxSysConfigController.getSysConfigParamValByCode(WxConstants.参数配置_军价上浮比例.getCode());
		String saleRatio = wxSysConfigController.getSysConfigParamValByCode(WxConstants.参数配置_对外销售价上浮比例.getCode());
		
		for(WxWzInputDetail wz : wzList) {
			wz.setArrivalKeyId(wz.getKeyId());
			wz.setKeyId(null);
			wz.setInputCode(input.getInputCode());
			//入库数量是到货数量减去不合格数量
			wz.setInputNum(wz.getArrivalNum().subtract(wz.getUnqualifiedNum()==null?BigDecimal.ZERO:wz.getUnqualifiedNum()));
			wz.setNowNum(wz.getInputNum());
			wz.setCreateTime(now);
			wz.setOrgNo(input.getOrgNo());
			wz.setArmyPrice(wz.getPurchasePrice().add(wz.getPurchasePrice().multiply(new BigDecimal(armRatio).divide(new BigDecimal(100))).setScale(2, BigDecimal.ROUND_HALF_UP)));
			wz.setSalePrice(wz.getPurchasePrice().add(wz.getPurchasePrice().multiply(new BigDecimal(saleRatio).divide(new BigDecimal(100))).setScale(2, BigDecimal.ROUND_HALF_UP)));
			inputAmount = inputAmount.add(wz.getPurchasePrice().multiply(wz.getInputNum()).setScale(2, BigDecimal.ROUND_HALF_UP));
			wzCodeList.add(wz.getWzNo());
			if(wzInputNumMap.containsKey(wz.getWzNo())) {
				wzInputNumMap.put(wz.getWzNo(), wz.getInputNum().add(wzInputNumMap.get(wz.getWzNo())));
			}else {
				wzInputNumMap.put(wz.getWzNo(), wz.getInputNum());
			}
		}
		input.setInputAmount(inputAmount);
		
		//入库操作
		iWxWzInputService.save(input);
		iWxWzInputDetailService.saveBatch(wzList);
		
		//更新到货单入库状态
		wxWzArrival.setIsInput(WxConstants.是.getCode());
		iWxWzArrivalService.updateById(wxWzArrival);
		
		//更新库存
		iWxWzNowNumService.wzNowNumAdd(wzCodeList, wzInputNumMap,input.getWarehouseCode());
		return businessContext;
	}

}
